package pe.com.drokasa.mirror.conexion;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InterruptedIOException;
import java.net.ProtocolException;
import java.net.Socket;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.net.UnknownServiceException;

/**
 * @author Synopsis S.A
 *
 */
public class SocketConnection 
{
	private String node_;
	private boolean alive_ = true;
	private int port_;
	private Socket socket_;
	private DataOutputStream output_;
	private DataInputStream input_;
	private String id;

	/**
	 * 
	 */
	public SocketConnection()
	{
		this.output_ = null;
		this.input_ = null;
		this.socket_ = null;
	}

	/**
	 * @param paramString
	 */
	public void setId(String paramString) 
	{
		this.id = paramString;
	}

	/**
	 * @param paramString
	 */
	public void setNode(String paramString)
	{
		this.node_ = paramString;
	}

	/**
	 * @return
	 */
	public String getNode()
	{
		return this.node_;
	}

	/**
	 * @param paramInt
	 */
	public void setPort(int paramInt)
	{
		this.port_ = paramInt;
	}

	/**
	 * @return
	 */
	public int getPort()
	{
		return this.port_;
	}

	/**
	 * @param paramArrayOfByte
	 * @throws IOException
	 */
	public void send(byte[] paramArrayOfByte) throws IOException
	{
		try
		{
			this.output_ = new DataOutputStream(this.socket_.getOutputStream());
		}
		catch (IOException e)
		{
			System.out.println("[" + this.id + "] " + "Node:" + getNode() + ", port:" + getPort() + ", Error al escribir en  socket: " + e);
		}

		try
		{
			this.output_.write(paramArrayOfByte, 0, paramArrayOfByte.length);
			this.output_.flush();
		}
		catch (IOException e)
		{
			this.alive_ = false;
			System.out.println("[" + this.id + "] " + "Node:" + getNode() + ", port:" + getPort() + ", Write data in socket error: " + e);
			throw e;
		}
	}

	/**
	 * @param paramInt
	 * @param paramLong
	 * @return
	 * @throws IOException
	 * @throws InterruptedIOException
	 */
	public byte[] receive(int paramInt, long paramLong) throws IOException, InterruptedIOException
	{
		int i = 0; int j = 0; int k = paramInt;
		byte[] arrayOfByte = new byte[paramInt];
		StringBuffer localStringBuffer = new StringBuffer();

		long l2 = System.currentTimeMillis();
		try
		{
			this.input_ = new DataInputStream(this.socket_.getInputStream());
		}
		catch (IOException e)
		{
			System.out.println("[" + this.id + "] " + "Node:" + getNode() + ", port:" + getPort() + ", Error al leer en socket: " + e);
		}

		try
		{
			int m = 1;
			do
			{
				long l1 = System.currentTimeMillis();
				paramLong -= l1 - l2;
				if (paramLong < 0L)
				{
					System.out.println("Create Interrruption.");
					throw new InterruptedIOException("Socket Timeout by Mirapi");
				}
				this.socket_.setSoTimeout((int)paramLong);
				j = this.input_.read(arrayOfByte);
				localStringBuffer.append(new String(arrayOfByte, 0, j));
				i += j;
				k -= j;
				arrayOfByte = new byte[k];
				m++;
			}
			while (i < paramInt);
			return localStringBuffer.toString().getBytes();
		}
		catch (InterruptedIOException e)
		{
			System.out.println("[" + this.id + "] " + "Node:" + getNode() + ", port:" + getPort() + ", timeout : " + paramLong + ", Socket Timeout " + e);
			throw e;
		}
		catch (IOException e)
		{
			System.out.println("[" + this.id + "] " + "Node:" + getNode() + ", port:" + getPort() + ", Error al leer socket: " + e);
			throw e;
		}
	}

	/**
	 * @throws UnknownHostException
	 * @throws ProtocolException
	 * @throws SocketException
	 * @throws UnknownServiceException
	 * @throws IOException
	 * @throws Exception
	 */
	public void connect() throws UnknownHostException, ProtocolException, SocketException, UnknownServiceException, IOException, Exception
	{
		int i = 0;
		Object localObject1 = null;
		try
		{
			this.socket_ = new Socket(getNode(), getPort());
			this.alive_ = true;
		} 
		catch (UnknownHostException localUnknownHostException) 
		{
			i = 1; localObject1 = localUnknownHostException; } catch (ProtocolException localProtocolException) {
			i = 1; localObject1 = localProtocolException; } catch (SocketException localSocketException) {
			i = 1; localObject1 = localSocketException; } catch (UnknownServiceException localUnknownServiceException) {
			i = 1; } catch (IOException localIOException) {
			i = 1; localObject1 = localIOException; } catch (Exception localException) {
			i = 1; localObject1 = localException;
		}
		finally
		{
			if (i != 0)
			{
				System.out.println("[" + this.id + "] " + "Node:" + getNode() + ", port:" + getPort() + ", Create socket error: " + ((Exception)localObject1).getMessage());
				this.alive_ = false;
				throw (Exception) localObject1;
			}
		}
	}

	/**
	 * 
	 */
	public void close()
	{
		try
		{
			this.input_.close();
			this.output_.close();
			this.socket_.close();
			this.input_ = null;
			this.output_ = null;
			this.socket_ = null;
			this.alive_ = false;
		}
		catch (IOException e)
		{
			System.out.println("[" + this.id + "] " + "Node:" + getNode() + ", port:" + getPort() + ", Close socket error: " + e);
		}
	}

	/**
	 * @return
	 */
	public boolean isAlive()
	{
		return this.alive_;
	}
}